<script lang="ts">
  import { login, register } from "$lib/api/user";
  import { appStore } from "$lib/stores/app.svelte";
  import { userStore } from "$lib/stores/user.svelte";
  import { request } from "$lib/utils/request";
  import { Modal, Tabs } from "@skeletonlabs/skeleton-svelte";
  import { X } from "lucide-svelte";
  import { getContext } from "svelte";
  import type { Store as ToastStore } from "@zag-js/toast";
  import { boardStore } from "$lib/stores/board.svelte";

  const toast: ToastStore = getContext("toast");

  const digitRe = /^\d+$/;
  const digitAndCharRe = /^[0-9a-zA-Z]+$/;

  let curTab = $state("login");

  let loginUsername = $state(localStorage.getItem("username") ?? "");
  let loginPasswd = $state("");

  let regUsername = $state("");
  let regDisplayName = $state("");
  let regPasswd = $state("");
  let regRePasswd = $state("");
  let regAuthCode = $state("");

  const valid = $derived(() => {
    if (curTab == "login") {
      if (loginUsername.trim() != "" && loginPasswd.trim() != "") {
        return true;
      }
    } else if (curTab == "register") {
      if (
        regUsername.trim() != "" &&
        regDisplayName.trim() != "" &&
        regPasswd.trim() != "" &&
        regPasswd == regRePasswd
      ) {
        if (appStore.serverCfg.quick_user_register) {
          if (regUsername.length > 0 && regUsername.length < 6) {
            return false;
          } else if (digitRe.test(regUsername.trim())) {
            return false;
          } else if (!digitAndCharRe.test(regUsername.trim())) {
            return false;
          }
          return true;
        } else {
          return regAuthCode != "";
        }
      }
    }
    return false;
  });

  async function doLogin() {
    const res = await request(
      login({
        user_name: loginUsername,
        passwd: loginPasswd,
      }),
    );
    userStore.userSession = res.session_id;
    userStore.userInfo = res.user_info;
    userStore.showLoginModal = false;
    await boardStore.init();

    toast.create({
      title: "成功",
      description: "登录成功!",
      type: "success",
    });

    localStorage.setItem("username", loginUsername);
  }

  async function doRegister() {
    await request(
      register({
        user_name: regUsername,
        passwd: regPasswd,
        reg_code: regAuthCode,
        basic_info: {
          display_name: regDisplayName,
          logo_uri: "",
        },
      }),
    );
    userStore.showLoginModal = false;
    toast.create({
      title: "成功",
      description: "注册成功!",
      type: "success",
    });
  }
</script>

<Modal
  open={true}
  triggerBase="btn preset-tonal"
  contentBase="card bg-surface-200-800 p-4 space-y-4 shadow-xl w-[500px]"
  backdropClasses="backdrop-blur-xs"
  backdropBase="backdrop-none"
  onOpenChange={(ev) => {
    if (!ev.open) {
      userStore.showLoginModal = false;
    }
  }}
>
  {#snippet content()}
    <div class="relative">
      <button
        type="button"
        class="btn preset-ghost-primary-500 absolute right-0 top-0"
        onclick={() => (userStore.showLoginModal = false)}
      >
        <X />
      </button>
      <Tabs value={curTab} onValueChange={(detail) => (curTab = detail.value)}>
        {#snippet list()}
          <Tabs.Control value="login">登录</Tabs.Control>
          {#if appStore.serverCfg.can_user_register}
            <Tabs.Control value="register">注册</Tabs.Control>
          {/if}
        {/snippet}
        {#snippet content()}
          <Tabs.Panel value="login">
            <label class="label">
              <span class="label-text">用户名</span>
              <input
                class="input bg-surface-50-950 rounded-none"
                type="text"
                bind:value={loginUsername}
                placeholder="请输入用户名"
              />
            </label>
            <label class="label">
              <span class="label-text">密码</span>
              <input
                class="input bg-surface-50-950 rounded-none"
                type="password"
                bind:value={loginPasswd}
                placeholder="请输入密码"
                onkeypress={(e) => {
                  if (
                    e.code == "Enter" &&
                    loginUsername != "" &&
                    loginPasswd != ""
                  ) {
                    doLogin();
                  }
                }}
              />
            </label>
          </Tabs.Panel>
          {#if appStore.serverCfg.can_user_register}
            <Tabs.Panel value="register">
              <label class="label">
                <span class="label-text">用户名</span>
                <input
                  class="input bg-surface-50-950 rounded-none"
                  type="text"
                  bind:value={regUsername}
                  placeholder="请输入用户名"
                />
                <span class="text-error-800-200 text-sm">
                  {#if regUsername.trim().length == 0}
                    &nbsp;
                  {:else if regUsername.length > 0 && regUsername.length < 6}
                    账号长度至少6位
                  {:else if digitRe.test(regUsername.trim())}
                    不能使用纯数字账号
                  {:else if !digitAndCharRe.test(regUsername.trim())}
                    只能使用数字和字母组合
                  {/if}
                </span>
              </label>
              <label class="label">
                <span class="label-text">昵称</span>
                <input
                  class="input bg-surface-50-950 rounded-none"
                  type="text"
                  bind:value={regDisplayName}
                  placeholder="请输入昵称"
                />
              </label>
              <label class="label">
                <span class="label-text">密码</span>
                <input
                  class="input bg-surface-50-950 rounded-none"
                  type="password"
                  bind:value={regPasswd}
                  placeholder="请输入密码"
                />
              </label>
              <label class="label">
                <span class="label-text">确认密码</span>
                <input
                  class={`input rounded-none ${regPasswd != regRePasswd ? "bg-error-400-600" : "bg-surface-50-950"}`}
                  type="password"
                  bind:value={regRePasswd}
                  placeholder="请重新输入上面的密码"
                />
              </label>
            </Tabs.Panel>
          {/if}
        {/snippet}
      </Tabs>
      <footer class="flex justify-end gap-4 mt-[20px]">
        <button
          type="button"
          class="btn preset-tonal"
          onclick={() => (userStore.showLoginModal = false)}>取消</button
        >
        <button
          type="button"
          class="btn preset-filled-primary-900-100"
          disabled={valid() == false}
          onclick={() => {
            if (curTab == "login") {
              doLogin();
            } else if (curTab == "register") {
              doRegister();
            }
          }}
        >
          {#if curTab == "login"}
            登录
          {:else if curTab == "register"}
            注册
          {/if}
        </button>
      </footer>
    </div>
  {/snippet}
</Modal>
